/**
 * @file tunnel_proxy_private.h
 *
 * @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
 *
 * @details
 *
 */

#ifndef _TUNNEL_PROXY_PRIVATE_H_
#define _TUNNEL_PROXY_PRIVATE_H_
#include "core_stdinc.h"
#include "core_sysdep.h"
#include "core_list.h"
#include "tunnel_buffer_mgr.h"
#include "tunnel_session_mgr.h"
#include "aiot_tunnel_api.h"

/* 定义隧道建连信息: host、port、path、token、tunnel_id最大长度*/
#define HOST_LEN_MAX             (128)
#define PORT_LEN_MAX             (8)
#define PATH_LEN_MAX             (128)
#define TOKEN_LEN_MAX            (128)

/* 定义本地服务：服务类型个数、服务名长度、服务类型长度、服务本地ip长度 */
#define SERVICE_LIST_MAX_CNT     (20)
#define SERVICE_NAME_LEN_MAX     (32)

/* 定义隧道的最多个数 */
#define MAX_PROXY_NUM            (20)

/* 定义消息最大长度：消息头，消息体 */
#define DEFAULT_MSG_HDR_LEN      (1024)
#define DEFAULT_MSG_BUFFER_LEN   (5 * DEFAULT_MSG_HDR_LEN)

/* 定义默认超时时间 */
#define DEFAULT_TIMEOUT_MS       (5000)

/**
 * @brief 本地服务类型的抽象描述
 *
 */
typedef struct REMOTE_SERVICE_NODE {
    /**
     * @brief 服务类型
     */
    char type[SERVICE_TYPE_LEN_MAX];
    /**
     * @brief 服务IP地址
     */
    char ip[SERVICE_IP_LEN_MAX];
    /**
     * @brief 服务端口号
     */
    uint32_t port;
    /**
     * @brief 服务链表，用户不用关心
     */
    struct core_list_head       node;
} LOCAL_SERVICE_NODE_S;

typedef struct
{
    uint32_t service_count;
    struct core_list_head       service_list;   //远程服务信息链表，其node为_lOCAL_SERVICE_NODE_S
} LOCAL_SERVICES_S;

typedef struct CLOUD_CHANNEL_PARAMS
{
    /* 建连配置：host、port、path、token、cred */
    char cloud_host[HOST_LEN_MAX];
    char cloud_port[PORT_LEN_MAX];
    char cloud_path[PATH_LEN_MAX];
    char token[TOKEN_LEN_MAX];
    void *cred;
    uint32_t trans_timeout;
    LOCAL_SERVICES_S *local_services;
} CLOUD_CHANNEL_PARAMS_S;

/*远程通道状态*/
typedef enum REMOTE_PROXY_STATE
{
    CLOUD_CHANNEL_CLOSED = 0,
    CLOUD_CHANNEL_CONNECTED,
    CLOUD_CHANNEL_ERROR,
} REMOTE_PROXY_STATE_E;

typedef struct RETRY_CONNECT_INFO
{
    int32_t retry_times;
    uint64_t connect_time;
} RETRY_CONNECT_INFO_S;

typedef struct REMOTE_PROXY_INFO
{
    aiot_sysdep_portfile_t*   sysdep;                      /* 底层依赖回调合集的引用指针 */
    CLOUD_CHANNEL_PARAMS_S   cloud_channel_params;         /* 连接云端通道的参数 */
    REMOTE_PROXY_STATE_E     cloud_channel_state;          /* 云通道的连接状态 */
    char                     tunnel_id[TUNNEL_ID_LEN_MAX]; /* 隧道ID */
    SESSION_LIST_S           session_list;                 /* 建立的session的管理hash表 */
    RA_BUFFER_INFO_S         cloud_read_buffer;            /* 接收云端数据使用的buffer，用于向本地服务转发 */
    RA_BUFFER_INFO_S         cloud_write_buffer;           /* 接收本地数据，向云端转发时使用的buffer */
    RETRY_CONNECT_INFO_S     retry_info;                   /* 重连记录参数 */
    int                      thread_running_cnt;           /* proxy线程运行计数器,用于判断线程是否正常运行 */
    int                      keepalive_cnt;                /* proxy线程运行计数器,用于判断线程是否正常运行 */
    unsigned int             remote_proxy_channel_switch;  /* 远程代理通道的开关 */
    unsigned int             has_switch_event;             /* 是否有开关事件 */
    void*                    lock;                         /* 锁，运行时资源防并发 */
    uint64_t                 ping_time;                    /* 发送心跳的时间 */
    uint64_t                 pong_time;                    /* 收到心跳的时间 */
    int                      status;                       /* 隧道状态0 close , 1 open */
    int                      close_code;                   /* 隧道关闭的原因 */
    void                    *cloud_conn;                   /* websocket句柄 */
} REMOTE_PROXY_INFO_S;

/* 隧道代理的创建、处理、回收 */
int init_remote_proxy_resource(REMOTE_PROXY_INFO_S *remote_proxy_info);
void remote_proxy_process(REMOTE_PROXY_INFO_S *remote_proxy_info);
int deinit_remote_proxy_resource(REMOTE_PROXY_INFO_S **remote_proxy);

#endif

